package guigu.Collection;

import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

/**
 * 1、list接口框架
 *
 *   |----Collection接口：单列集合，用来存储一个一个的对象
 *           |----List接口：存储有序的、可重复的数据。 --->"动态数组"
 *                |---ArrayList:作为List接口的主要实现类；线程不安全的效率高；底层使用Object[] elementData存储
 *                |---LinkedList：对于频繁的插入、删除操作，使用此类效率比ArrayList高；底层使用双向链表存储
 *                |---Vector：作为List接口的古老实现类；线程安全的，效率低；底层使用Object[] elementData存储
 *
 * 2、ArrayList的源码分析：
 *
 *    2.1 jdk 7情况下：
 *      ArrayList list = new ArrayList()://底层创建了长度是10的Object[]数组elementData
 *      list.add(123);//elementData[0] = new Integer(123);
 *      ...
 *      list.add(11);//如果此次的添加导致底层elementData数组容量不够，则扩容。
 *      默认情况下，扩容为原来的容量的1.5倍，同时需要将原有数组中的数据复制到新的数组中。
 *
 *       结论：建议开发中使用带参的构造器：ArrayList list = new ArrayList(int capacity)
 *
 *    2.2 jdk 8中ArrayList的变化：
 *       ArrayList list = new ArrayList();//底层Object[] elementData初始化为{},并没有创建长度是10的Object[]数组elementData
 *
 *       list.add(123);//第一次调用add()时，底层才创建了长度10的数组，并将数据123添加到elementData[0]
 *       ...
 *      后续的添加和扩容操作与jdk 7 无异。
 *
 *    2.3 小结：jdk 7中的ArrayList的对象的创建类似于单例的饿汉式，而jdk8中的ArrayList的对象的创建类似于单例的懒汉式，延迟了
 *             数组的创建，节省内存。
 *
 * 3、LinkedList的源码分析：
 *      LinkedList list = new LinkedList();内部声明了Node类型的first和last属性，默认值为null
 *      list.add(123);//将123封装到Node中，创建了Node对象。
 *
 *      其中，Node定义为：体现了LinkedList的双向链表的说法
 *          private static class Node<E> {
                 E item;
                 Node<E> next;
                 Node<E> prev;

                 Node(Node<E> prev, E element, Node<E> next) {
                 this.item = element;
                 this.next = next;
                 this.prev = prev;
                 }
                 }
  4、Vector的源码分析：jdk7和jdk8中通过Vector()构造器创建对象时，底层都创建了长度为10的数组
    在扩容方面，默认扩容为原来的数组长度的2倍。

 *  面试题：ArrayList、LinkedList、Vector三者的异同？
 *  同：三个都实现了List接口，存储数据的特点相同：存储有序的、可重复的数据
 *  不同：见上
 *
 *  5、List常用方法测试
 *
 *    void add(int index,Object ele):在index位置插入ele元素
 *    boolean addAll(int index,Collection eles):从index位置开始将eles中的所有元素添加进来
 *    Object get(int index):获取指定index位置的元素
 *    int indexOf(Object obj):返回obj在集合中首次出现的位置
 *    int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置
 *    Object remove(int index):移除指定index位置的元素，并返回此元素
 *    Object set(int index,Object ele):设置指定index位置的元素为ele
 *    List subList(int fromIndex,int toIndex):返回从fromIndex到toIndex位置的子集合
 *
 *    总结：常用方法
 *    增：add(Object ele)
 *    删：remove(int index) / remove(Object obj)
 *    改：set(int index,Object ele)
 *    查：get(int index)
 *    长度：size()
 *    遍历：① Iterator迭代器方式
 *          ② 增强for循环
 *          ③ 普通的循环
 */
public class ListTest {

    @Test
    public void test1()
    {
        ArrayList list = new ArrayList();
        list.add(132);
        list.add("石文学");
        list.add("憨儿子");
        list.add(new String("Tom"));
        list.add("I love you");
        list.add(132);
        Object[] objects = list.toArray();
        for(int i=0;i<objects.length;i++)
        {
            System.out.println(objects[i]);
        }

        //遍历
        //① Iterator迭代器方式
        /*Iterator iterator = list.iterator();
        while(iterator.hasNext())
        {
            System.out.println(iterator.next());
        }*/

        //② 增强for循环
        /*for(Object obj : list)
        {
            System.out.println(obj);
        }*/

        //③ 普通的循环
       /* for(int i=0;i<list.size();i++)
        {
            System.out.println(list.get(i));
        }*/

        //void add(int index,Object ele):在index位置插入ele元素
       // list.add(4,789);
        //System.out.println(list);

        //boolean addAll(int index,Collection eles):从index位置开始将eles中的所有元素添加进来
//        List list1 = Arrays.asList(4, 5, 6);
//        list.addAll(3,list1);
//        System.out.println(list);

        //Object get(int index):获取指定index位置的元素
//        Object o = list.get(3);
//        System.out.println(o);

        //int indexOf(Object obj):返回obj在集合中首次出现的位置
//        int i = list.indexOf(132);
//        System.out.println(i);

        //int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置
//        int i = list.lastIndexOf(258);
//        System.out.println(i);
    }

    @Test
    public void test2()
    {
        ArrayList list = new ArrayList();
        list.add(132);
        list.add("石文学");
        list.add("憨儿子");
        list.add(new String("Tom"));
        list.add("I love you");
        list.add(132);

        //Object remove(int index):移除指定index位置的元素，并返回此元素
//        Object remove = list.remove(3);
//        System.out.println(remove);

        //Object set(int index,Object ele):设置指定index位置的元素为ele
//        Object set = list.set(2, 147);
//        System.out.println(set);
//        System.out.println(list);

        //List subList(int fromIndex,int toIndex):返回从fromIndex到toIndex位置的子集合
        List list1 = list.subList(2, 5);
        System.out.println(list1);
        System.out.println(list);
    }
}
